home *** CD-ROM | disk | FTP | other *** search
/ BMUG Revelations / BMUG Revelations.toast / Utilities / Network / Find Printers v1.1 / testATP.c < prev   
C/C++ Source or Header  |  1991-10-22  |  12KB  |  434 lines

  1. #ifdef COMMENT
  2.  
  3.     |    testATP.c
  4.     |
  5.     |    This program scans the AppleTalk network for all LaserPrinter servers
  6.     |    and displays them in a list. This is the Beta-test for a project which
  7.     |    I'm working on currently. I though it might be of interest to those
  8.     |    exploring the preferred AppleTalk interface.
  9.     |
  10.     |    <c>1991 Mike Carter, MCDesign. You may use portions of this code if you like,
  11.     |    as long as authorship is acknowledged. Bug reports and any (and all) comments
  12.     |    are welcome! You can reach me via E-Mail at CompuServe 76114,321.
  13.     |
  14.     |    'FindPrinters' is a trademark of MCDesign. All rightrs reserved.
  15.     |
  16.     |    (Be sure to include these libraries in your project: AppleTalk, nAppleTalk, MacTraps)
  17.     
  18. #endif
  19.  
  20. #define SEARCH                1                /* Dialog items */
  21. #define LIST                2
  22. #define NUMFOUND            3
  23. #define DONE                4
  24. #define LINE                8
  25. #define ICON                9
  26. #define MSG                    10
  27.  
  28. #define LOOKING                1                /* Message strings */
  29. #define LOOKUPERR            2
  30. #define EXTRACTERR            3
  31. #define NO_DEVICES            4
  32. #define ALL_DONE            5
  33.  
  34. #define BASE_RES            128
  35. #define NIL_POINTER            0L
  36. #define    WNE_TRAP_NUM        0x60
  37. #define    UNIMPL_TRAP_NUM        0x9F
  38.  
  39. #include <nAppleTalk.h>
  40.  
  41. void DrawTheLine( DialogPtr theDlog );        /* Draws a dotted line on a userItem */
  42. void DoAlert( short );                        /* Changes message area in DLOG */
  43. int findPrinters( Str32 *, short * );        /* does all the ATP stuff */
  44.  
  45. Str32            theObj = "\p=";                    /* Anything... */
  46. Str32            theType = "\pLaserWriter";        /* of type LaserPrinter... */
  47. Str32            theZone = "\p*";                /* in our zone. */
  48. DialogPtr        mainDlog;
  49. GrafPtr            oldPort;
  50. short            maxToGet = 25;                    /* max number to find */
  51. short            numFound = 0;                    /* number found in search */
  52.  
  53. Str32            pNames[25];                        /* array for found printers */
  54. ListHandle        theListH;
  55. Boolean            gDone = false;
  56. Boolean            gWNElmplemented;
  57. EventRecord        gTheEvent;
  58. Ptr                theBuff, ePtr;                    /* NBP receive buffer; entity pointer */
  59. int                buffSize;                        /* size of buffer */
  60. CursHandle        WatchCursor;
  61. Str255    brag = "\pFindPrinters <c>1991 MCDesign. Written by Mike Carter (76114,321) in Think C";
  62.  
  63.  
  64. /*********************** main *****************************/
  65. main()
  66. {
  67.     MaxApplZone();                        /* get some ROOM!!!! */
  68.     InitMac();                            /* initialize Mac Managers */
  69.     
  70.     /* Allocate our main memory-gobbling structures so they end */
  71.     /* up at the bottom of our heap, causing much less heap     */
  72.     /* fragmentation. I call this semi-dynamic allocation!      */
  73.     
  74.     buffSize = (sizeof( EntityName ) + 4) * maxToGet;
  75.  
  76.     theBuff = NewPtrClear( buffSize );
  77.     if( theBuff == 0L ) 
  78.         ExitToShell();                    /* No memory!! */
  79.     
  80.     ePtr = NewPtrClear( 100 );            /* size for NBPSetentitiy */
  81.     if( ePtr == 0L ) 
  82.         ExitToShell();                    /* no memory!! */
  83.     
  84.     SetUpDlog();                        /* load and show our main dialog */
  85.     
  86.     LoopTheLoop();                        /* main event loop */
  87.     
  88.     /* clean-up routines */
  89.     LDispose( theListH );                /* Can't say whether or not these  */
  90.     DisposPtr( ePtr );                    /* are _really_ necessary, seeing  */
  91.     DisposPtr( theBuff );                /* that quitting the app. releases */
  92.     DisposDialog( mainDlog );            /* it's memory anyway--but what the */
  93.                                         /* heck! can't hurt!!                */
  94.     
  95.     SetPort( oldPort );                    /* Set the GrafPort back the way we found it */
  96.         
  97.     ExitToShell();                        /* ta-ta for now */
  98. }
  99.  
  100. /*********************** InitMac **************************/
  101. InitMac()
  102. {
  103.     InitGraf( &thePort );                /* Initialize the Mac Managers */
  104.     InitFonts();
  105.     FlushEvents( everyEvent, 0 );
  106.     InitWindows();
  107.     InitMenus();
  108.     TEInit();
  109.     InitDialogs( 0L );
  110.     InitCursor();
  111.     
  112.     WatchCursor=GetCursor( watchCursor );
  113.     HNoPurge((Handle)WatchCursor);
  114. }
  115.  
  116. /******************** SetUpDlog *****************************/
  117. SetUpDlog()
  118. {
  119.     int            type = 0, hit = 0;
  120.     Rect        box;
  121.     Handle        itemH;
  122.     
  123.     mainDlog = GetNewDialog( BASE_RES + 1, 0L, -1L );    /* Get our main Dialog */
  124.     if( mainDlog == 0L )
  125.         ExitToShell();
  126.     
  127.     GetPort( &oldPort );                /* Let's be port-friendly */
  128.     SetPort( mainDlog );
  129.     
  130.     SetUpList();                        /* define the list which shows the printer names */
  131.     
  132.     ShowWindow( mainDlog );                /* become visual reality */
  133.     DrawDialog( mainDlog );                /* draw the guts */
  134.     
  135.     FrameListRect();                    /* frame the list's rect */
  136.     
  137.     DrawButton( mainDlog );                /* outline the default button */
  138.     DrawTheLine( mainDlog );            /* draw the line seperating the message area */
  139. }
  140.  
  141. /****************** SetUpList ********************************/
  142. SetUpList()
  143. {
  144.     int        type, i;
  145.     Rect    box, dataBounds, rView;
  146.     Point    cSize;
  147.     Handle    itemH;
  148.     Cell    theCell;
  149.     
  150.     GetDItem( mainDlog, LIST, &type, &itemH, &box );
  151.     
  152.     rView = box;                        /* Get rect size from our DITL user item */
  153.     rView.left+=1;                        /* leave room for framerect */
  154.     rView.right-=16;                    /* room for scrool bar and framerect */
  155.     rView.bottom -= 1;                    /* room for framerect */
  156.     
  157.     cSize.h = rView.right - rView.left;                /* set cell size */
  158.     cSize.v = (rView.bottom - rView.top) / 6;        /* show 6 cells at a time */
  159.     
  160.     SetRect(&dataBounds,0,0,1,maxToGet);            /* define cell structure */
  161.     
  162.     theListH = LNew(&rView, &dataBounds, cSize, 0L, mainDlog, true, false, false, true);
  163.     (**theListH).selFlags = lOnlyOne+lNoDisjoint+lNoExtend+lNoNilHilite;
  164.     
  165. }
  166.  
  167. /**************************** LoopTheLoop ***************************/
  168. LoopTheLoop()
  169. {
  170.     /*    MAIN LOOP SEGMENT!!!!!
  171.      *
  172.      *    Is WaitNextEvent() implemented?  If it is, the address of the
  173.      *    WaitNextEvent() trap will be different than the standard,
  174.      *    "unimplemented" trap...
  175.      */
  176.      
  177.     gWNElmplemented = ( NGetTrapAddress( WNE_TRAP_NUM, ToolTrap ) !=
  178.                             NGetTrapAddress( UNIMPL_TRAP_NUM, ToolTrap ) );
  179.     
  180.     /*
  181.      *    Don't wait for a mouse click. Retrieve and process events
  182.      *    instead!
  183.      */
  184.  
  185.     while ( gDone == false )
  186.     {
  187.         HandleEvent();
  188.     }
  189. }
  190.  
  191. /************************** HandleEvent *****************************/
  192. HandleEvent()
  193. {
  194.     int        theItem, type;
  195.     Handle    itemH;
  196.     Rect    box;
  197.     Point    pt;
  198.     int        err = 0;
  199.  
  200.     if ( gWNElmplemented )                        /* Use appropriate event routine */
  201.         WaitNextEvent( everyEvent, &gTheEvent, 0L, 0L );
  202.     
  203.     else
  204.     {
  205.         SystemTask();
  206.         GetNextEvent( everyEvent, &gTheEvent );
  207.     }
  208.  
  209.     if (IsDialogEvent( &gTheEvent ) )            /* event happened inside the Dlog?? */
  210.     {
  211.         if ( DialogSelect( &gTheEvent, &mainDlog, &theItem ) )        /* yes it did!! */
  212.         {
  213.             switch( theItem )
  214.             {
  215.                 case SEARCH:
  216.                     SetCursor(*WatchCursor);
  217.                     err = findPrinters( pNames, &numFound );
  218.                     InitCursor();
  219.                     if( err != noErr)
  220.                         SysBeep( 30 );
  221.                     break;
  222.                     
  223.                 case DONE:
  224.                     gDone = true;
  225.                     return;                /* fall all the out to LoopTheLoop */
  226.                     break;
  227.                     
  228.                 case LIST:
  229.                     pt = gTheEvent.where;
  230.                     GlobalToLocal( &pt );
  231.                     LClick( pt, gTheEvent.modifiers, theListH );
  232.                     break;
  233.                     
  234.                 case ICON:
  235.                     GetDItem( mainDlog, MSG, &type, &itemH, &box );    /* secret brag switch! */
  236.                     SetIText( itemH, &brag );
  237.                     break;
  238.             }
  239.             gTheEvent.what = nullEvent;        /* so the following switch won't handle it */
  240.         }
  241.     }
  242.         
  243.     switch ( gTheEvent.what )        /* Okay, event wasn't part of dialog */
  244.     {
  245.         case nullEvent:
  246.             break;
  247.  
  248.         case mouseDown:
  249.             HandleMouseDown();
  250.             break;
  251.         
  252.         case keyDown:                /* don't need to list them */
  253.         case keyUp:
  254.         case autoKey:
  255.             break;
  256.             
  257.         case updateEvt:
  258.             BeginUpdate( gTheEvent.message );
  259.             DrawDialog( mainDlog );
  260.             FrameListRect();
  261.             EndUpdate( gTheEvent.message );
  262.             break;
  263.     }
  264. }
  265.  
  266. /*********************** HandleMouseDown ******************/
  267. HandleMouseDown()
  268. {
  269.         WindowPtr    whichWindow;
  270.         short int    thePart;
  271.         long        windSize;
  272.         GrafPtr        oldPort;
  273.         Rect        dragRect = screenBits.bounds;
  274.  
  275. /*    First, find out which window the mouse click occurred in.
  276.  *    Then, find out what part of the window the mouse click occurred in.
  277.  */
  278.  
  279.     thePart = FindWindow( gTheEvent.where, &whichWindow );
  280.     switch ( thePart )
  281.     {
  282.         case inSysWindow :             /*    Probably a desk accessory window... */
  283.             SystemClick( &gTheEvent, whichWindow );
  284.             break;
  285.             
  286.         case inDrag:                /* Drag the window around the screen, limited by dragRect */
  287.             DragWindow( whichWindow, gTheEvent.where, &dragRect);
  288.             break;
  289.     }
  290. }
  291.  
  292. /**************************** FrameListRec **************************/
  293. FrameListRect()
  294. {
  295.     int        type;
  296.     Rect    box;
  297.     Handle    itemH;
  298.     
  299.     GetDItem( mainDlog, LIST, &type, &itemH, &box );
  300.     box.top -= 1;
  301.     FrameRect( &box );
  302.     
  303.     DisposHandle( itemH );
  304. }
  305.  
  306. /************************** findPrinters ****************************/
  307. int findPrinters( Str32 *pNames, short *numFound)
  308. {
  309.     EntityName        aFoundPrinter;            /* holds info for found printers */
  310.     AddrBlock        entityAddr;                /* address for found printers */
  311.     int                type = 0, i = 0;        /* Dlog stuff */
  312.     long            dummy;                    /* Delay() dummy var */
  313.     Handle            itemH;                    /* Dlog stuff */
  314.     Rect            box;                    /* ditto. */
  315.     Str255            look, numStr;                /* a mesage */
  316.     MPPParamBlock    p;                        /* preferred interface paramBlock */
  317.     Ptr                ePtr;                    /* pointer to entity stuff */
  318.     OSErr            err;                    /* OS err value */
  319.     Cell            theCell;                /* for the Dlog list */
  320.  
  321.     GetIndString(  &look, BASE_RES, LOOKING );        /* load a message */
  322.     GetDItem( mainDlog, MSG, &type, &itemH, &box );
  323.     SetIText( itemH, &look );
  324.  
  325.     
  326.     NBPSetEntity( ePtr, theObj, theType, theZone );        /* setup up the entity */
  327.     
  328.     p.ioCompletion = 0L;                /* no completion procedure */
  329.     p.NBPinterval = 2;                    /* interval of two */
  330.     p.NBPcount = 3;                        /* retry three times only */
  331.     p.NBPentityPtr = ePtr;                /* the entity info */
  332.     p.NBPretBuffPtr = theBuff;            /* return buffer */
  333.     p.NBPretBuffSize = buffSize;
  334.     p.NBPmaxToGet = maxToGet;            /* maximum entities to find */
  335.     
  336.     err = PLookupName( &p, false );        /* go lookin' */
  337.     if( err != noErr )
  338.     {
  339.         DoAlert( LOOKUPERR );
  340.         return( -1 );
  341.     }
  342.     
  343.     if( p.NBPnumGotten <= 0 )
  344.     {
  345.         DoAlert( NO_DEVICES );                    /* error code for none found */
  346.         return( -1 );
  347.     }
  348.     
  349.     NumToString( p.NBPnumGotten, &numStr  );
  350.     GetDItem( mainDlog, NUMFOUND, &type, &itemH, &box );
  351.     SetIText( itemH, &numStr );
  352.     
  353.     for( i = 1; i <= p.NBPnumGotten; i++ )    /* cycle thru and extract */
  354.     {
  355.         err = NBPExtract( theBuff, p.NBPnumGotten, i, &aFoundPrinter, &entityAddr );
  356.         if( err != noErr )
  357.         {
  358.             DoAlert( EXTRACTERR );
  359.             return( -1 );
  360.         }
  361.             
  362.         BlockMove( (Ptr)&aFoundPrinter.objStr, (Ptr)&pNames[i], aFoundPrinter.objStr[0] );
  363.         theCell.h = 0; theCell.v = i - 1;
  364.         LSetCell( (Ptr)&aFoundPrinter.objStr[1], aFoundPrinter.objStr[0], theCell, theListH );
  365.         LDraw( theCell, theListH );
  366.     } 
  367.     
  368.     GetIndString(  &look, BASE_RES, ALL_DONE );        /* load a message */
  369.     GetDItem( mainDlog, MSG, &type, &itemH, &box );
  370.     SetIText( itemH, &look );
  371.  
  372.     return( 0 );        /* all is well */
  373. }
  374.  
  375. /*********************** DoAlert ************************/
  376. void DoAlert( short index )
  377. {
  378.     int        type;
  379.     Rect    box;
  380.     Handle    itemH;
  381.     Str255    errStr;
  382.     
  383.     GetDItem( mainDlog, MSG, &type, &itemH, &box );
  384.     GetIndString( &errStr, BASE_RES, index );
  385.     
  386.     SetIText( itemH, &errStr );
  387.     DisposHandle( itemH );
  388. }
  389.  
  390.  
  391. /********************** DrawTheLine ***********************/
  392. void DrawTheLine( DialogPtr theDlog )
  393. /* 
  394.     |    This function will, utilizing the Rect defined in the user item
  395.     |    within the rez file, draw a dotted line to seperate the message
  396.     |    line at the bottom of the DLOG from the parts above it.
  397. */
  398. {
  399.     Handle    itemH;
  400.     Rect    box, theRect;
  401.     Point    where, left, right;
  402.     int        type;
  403.     
  404.     GetDItem( theDlog, LINE, &type, &itemH, &box );
  405.     
  406.     PenPat( ltGray );
  407.     PenSize( 1, 1 );
  408.     
  409.     MoveTo( box.left, box.top );
  410.     LineTo( box.right, box.top );
  411.     
  412.     PenNormal();
  413. }
  414.  
  415. /*************************** ButtonDraw ****************/
  416. DrawButton( theDialog )
  417. DialogPtr    theDialog;
  418. {
  419.     int        itemType;
  420.     Rect    itemRect;
  421.     Handle    item;
  422.     GrafPtr    oldPort;
  423.     
  424.     GetDItem( theDialog, SEARCH, &itemType, &item, &itemRect );
  425.     GetPort( &oldPort );
  426.     SetPort( theDialog );
  427.     
  428.     PenSize( 3,3 );
  429.     InsetRect( &itemRect, -4, -4 );
  430.     FrameRoundRect( &itemRect, 16, 16 );
  431.     PenNormal();
  432.     
  433.     SetPort( oldPort );
  434. }